package eg.backend.domain;

import java.util.Date;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

import org.datanucleus.jpa.annotations.Extension;

@Entity
@NamedQueries({
	@NamedQuery(name="Expense.getByKey", query = "select e from eg.backend.domain.Expense e where e.id =:id"),
	@NamedQuery(name="Expense.findDaily", query="select e from eg.backend.domain.Expense e where e.date >= :from and e.date < :to and e.owner = :user"),
	@NamedQuery(name="Expense.findChildrenByDimension", query="select t from eg.backend.domain.Expense t where t.dimensions.contains(:dimensionId)"),
	@NamedQuery(name="Expense.findMinDate", query="select e.date from eg.backend.domain.Expense e where e.owner = :user order by e.date asc"),
	@NamedQuery(name="Expense.findMaxDate", query="select e.date from eg.backend.domain.Expense e where e.owner = :user order by e.date desc"),
	@NamedQuery(name="Expense.getTotalOfCategory", query="select e.amount from eg.backend.domain.Expense e where e.owner = :owner and e.category = :category"+
			" and e.date >= :from and e.date < :to"),
	@NamedQuery(name="Expense.getTotalOfTag", query="select e.amount from eg.backend.domain.Expense e where e.owner = :owner" +
			" and (e.tags = :tagName or e.tags like :tagName || ',%' or e.tags like '%,' || :tagName || ',%' or e.tags like '%,' || :tagName)" +
			" and e.date >= :from and e.date < :to")
})
//	//use sql to query joined table "expense_dimension"
//	@NamedQuery(name = "Expense.findExpenseIdsByDimension", query = "select distinct expense_id from expense_dimension where dimension_id in (:dimensionIds)")

public class Expense {
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Extension(vendorName = "datanucleus", key = "gae.encoded-pk", value = "true")
	private String id;

	@Temporal(TemporalType.DATE)
	private Date inputDate;
	
	private String category;

	private Set<String> dimensions = new HashSet<String>();

	public String owner;

	//separated by Constants.TAG_SEPARATOR
	private String tags;
	
	private String name;
	private float amount;

	@Temporal(TemporalType.DATE)
	public Date date;
	private String remark;
	
	private String shop;

	private String shopName;

	public String getShop() {
		return shop;
	}

	public void setShop(String shop) {
		this.shop = shop;
	}

	public String getShopName() {
		return shopName;
	}

	public void setShopName(String shopName) {
		this.shopName = shopName;
	}
	
	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public Date getInputDate() {
		return inputDate;
	}

	public void setInputDate(Date inputDate) {
		this.inputDate = inputDate;
	}

	public String getCategory() {
		return category;
	}

	public void setCategory(String category) {
		this.category = category;
	}

	public Set<String> getDimensions() {
		return dimensions;
	}

	public void setDimensions(Set<String> dimensions) {
		this.dimensions = dimensions;
	}
	
	public void addDimension(String dimension) {
		this.dimensions.add(dimension);
	}
	
	public void removeDimension(String dimension) {
		this.dimensions.remove(dimension);
	}
	
	public String getOwner() {
		return owner;
	}

	public void setOwner(String owner) {
		this.owner = owner;
	}

	public String getTags() {
		return tags;
	}

	public void setTags(String tags) {
		this.tags = tags;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public float getAmount() {
		return amount;
	}

	public void setAmount(float amount) {
		this.amount = amount;
	}

	public Date getDate() {
		return date;
	}

	public void setDate(Date date) {
		this.date = date;
	}

	public String getRemark() {
		return remark;
	}

	public void setRemark(String remark) {
		this.remark = remark;
	}

	public String getExistingShopName() {
//		return this.getShop() == null ? "" : this.getShop();//.getName();
		return this.getShopName() == null ? "" : this.getShopName();
	}
}
